package com.wypiwyl.footastic.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.wypiwyl.footastic.Arena;
import com.wypiwyl.footastic.Direction;
import com.wypiwyl.footastic.FootasticActivity;
import com.wypiwyl.footastic.Player;
import com.wypiwyl.footastic.PlayerKey;
import com.wypiwyl.footastic.R;
import com.wypiwyl.footastic.model.Util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.ArcShape;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.graphics.PorterDuff;

public class GrassView extends SurfaceView implements SurfaceHolder.Callback {

    // declaration log
    private static final String TAG = "GrassView";

    /** **/
    // initialisation du nombre de cases du calque
    private static int NB_X_CASE = 28;
    private static int NB_Y_CASE = 16;
    // taille d'une case
    private static final int D_CASE = 42;
    public static final int W_CASE = D_CASE;
    public static final int H_CASE = D_CASE;
    // taille des bords de la pelouse
    public static final int W_PADDING = 42;
    public static final int H_PADDING = 42;

    /** declaration des images **/
    // declaration de l'image de fond
    private final Drawable img_terrain;
    // declaration de l'image du ballon
    private static Drawable img_ball;

    /** declaration des couleurs **/
    // couleurs des lignes de la grille
    public static Paint paintGrid1 = new Paint();
    public static Paint paintGrid2 = new Paint();

    private Point mPass = null;

    /** declaration des calques **/
    // liste des calques de joueur
    public Map<PlayerKey, PlayerLayer> lPlayerLayer = new HashMap<PlayerKey, PlayerLayer>();

    private SurfaceHolder mSurfaceHolder;

    private Context mContext;

    static {
        // affectation des parametres pour les couleurs des selections du ballon
        paintGrid1.setAntiAlias(true);
        paintGrid1.setARGB(100, 0, 255, 0);
        paintGrid2.setAntiAlias(true);
        paintGrid2.setARGB(100, 0, 100, 0);
    }

    public GrassView(Context context, AttributeSet attrs) {

        super(context, attrs);
//        super(context);

        //
        mContext = context;

        // on specifie notre interet pour la surface
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);
        this.mSurfaceHolder = holder;

        //
        //        super(new Rect(x, y, NB_X_CASE * W_CASE, NB_Y_CASE * H_CASE), context.getResources().getDrawable(R.raw.terrain));

        /** initialisation des images **/
        // initialisation de l'image de fond
        img_terrain = mContext.getResources().getDrawable(R.raw.terrain);
        // initialisation de l'image du ballon
        img_ball = mContext.getResources().getDrawable(R.raw.ballon);

        // initialisation des calques des joueurs
        initGame();
    }

    public void refreshCanvas() {

        Canvas c = null;

        try {
            c = mSurfaceHolder.lockCanvas(null);
            onDraw(c);
        } finally {
            if (c != null) {
                mSurfaceHolder.unlockCanvasAndPost(c);
            }
        }
    }
    
    public void scroll() {

        Canvas c = null;

        try {
            c = mSurfaceHolder.lockCanvas(null);
            onDraw(c);
        } finally {
            if (c != null) {
                mSurfaceHolder.unlockCanvasAndPost(c);
            }
        }
    }

    public void initGame() {

        lPlayerLayer.clear();

        /** initialisation des calques **/
        // initialisation des calques de joueurs
        for (Player player : Arena.getInstance().getAllPlayer()) {
            //
            PlayerLayer playerLayer = new PlayerLayer(player, W_CASE, H_CASE, mContext);
            lPlayerLayer.put(player.getPlayerKey(), playerLayer);
        }

        mPass = null;
        Flags.getInstance().setPasseDone(false);
        Flags.getInstance().unselectPass();
    }

    public void initRound() {

        // on reinitialise la position de passe
        mPass = null;

        for (PlayerLayer playerLayer : lPlayerLayer.values()) {
            playerLayer.initRound();
        }
    }

    public void doJobDown(MotionEvent event) {

        Log.i(TAG, this.getClass().getName() + ".doJobDown" + " - BEGIN");

        // on verifie si aucun joueur n'est deja selectionne
        if (!Flags.getInstance().isPlayerSelected()) {

            Point positionEvent = Util.getPoint(event);

            Player playerSelected = getPlayer(positionEvent);

            if (playerSelected != null && Arena.getInstance().isPlayerTurn(playerSelected)) {

                // on ajoute les indicateurs sur la selection du joueur
                Flags.getInstance().selectPlayer();
                Flags.getInstance().addPlayerKeySelected(playerSelected.getPlayerKey());

                // on recupere la cle du joueur selectionne
                PlayerKey playerKey = playerSelected.getPlayerKey();
                // on recupere le calque du joueur selectionne
                PlayerLayer playerSelectedLayer = lPlayerLayer.get(playerKey);

                // on initialise le chemin du joueur
                playerSelectedLayer.initPath(positionEvent);
            }

            // TODO : arevoir
            // on verifie si un joueur possede le ballon et si la passe est selectionnee
            if (Arena.getInstance().isOwnerBall() && Flags.getInstance().isPassSelected()) {
                // on recupere le joueur possedant le ballon
                playerSelected = Arena.getInstance().getOwnerBall();

                /** on verifie si une passe n'est pas effectuee **/
                // FIXME PASSE
                //            if (!action && Flags.getInstance().isBallSelected() && playerSelectedLayer.isPassing(positionEvent)) {
                //            if (!action && Flags.getInstance().isBallSelected() && Util.getDistance(playerSelected.getPosition(), positionEvent) <= 400) {
                if (/* !action && Flags.getInstance().isBallSelected() && */true/*
                                                                                 * Util
                                                                                 * .
                                                                                 * isPassePossible
                                                                                 * (
                                                                                 * playerSelected
                                                                                 * ,
                                                                                 * positionEvent
                                                                                 * )
                                                                                 */) {

                    //
                    mPass = positionEvent;
                    // changement de la position du ballon
                    //                Arena.getInstance().setPositionBall(positionReelle);

                    //                    int incrementX = deltaX / nbSequence;
                    //                    int incrementY = deltaY / nbSequence;
                    //
                    //                    for (int i = 0; i < nbSequence; i++) {
                    //                        Point positionBall = Arena.getInstance().getPositionBall();
                    //                        Point positionIntermediaire = new Point(positionBall.x + incrementX, positionBall.y + incrementY);
                    //
                    //                        Arena.getInstance().setPositionBall(positionIntermediaire);
                    //
                    //                        Log.w(TAG, "TEST");
                    //                    }

                    //                    Arena.getInstance().setPositionBall(positionReelle);

                    Flags.getInstance().setPasseDone(true);

                    // deselection du proprietaire du ballon
                    //                    Arena.getInstance().setOwnerBall(null);
                }
            }

        }

        refreshCanvas();

        Log.i(TAG, this.getClass().getName() + ".doJobDown" + " - END");
    }

    public void doMove(MotionEvent event) {

        Log.v(TAG, this.getClass().getName() + ".doMove" + " - BEGIN");

        // on verifie si un joueur est deja selectionne
        if (Flags.getInstance().isPlayerSelected()) {
            // on recupere la cle du joueur selectionne
            PlayerKey playerKey = Flags.getInstance().getPlayerKeySelected();
            // on recupere le calque du joueur selectionne
            PlayerLayer playerSelectedLayer = lPlayerLayer.get(playerKey);
            //
            // FIXME conversion ici ?
            playerSelectedLayer.recordPath(Util.getPoint(event));
        }

        refreshCanvas();

        Log.v(TAG, this.getClass().getName() + ".doMove" + " - END");
    }

    public void doJobUp(MotionEvent event) {

        Log.i(TAG, this.getClass().getName() + ".doJobUp" + " - BEGIN");

        // on verifie si un joueur est deja selectionne
        if (Flags.getInstance().isPlayerSelected()) {
            //
            // on recupere la cle du joueur selectionne
            PlayerKey playerKey = Flags.getInstance().getPlayerKeySelected();
            // on recupere le calque du joueur selectionne
            PlayerLayer playerSelectedLayer = lPlayerLayer.get(playerKey);

            playerSelectedLayer.endPath(Util.getPoint(event));
            // on enleve les indicateurs sur la selection du joueur
            Flags.getInstance().unselectPlayer();
            Flags.getInstance().initPlayerKeySelected();
            // on enleve les indicateurs sur la selection du ballon
            Flags.getInstance().unselectBall();
        }

        refreshCanvas();

        Log.i(TAG, this.getClass().getName() + ".doJobUp" + " - END");
    }

    //    public void doJobUp(Point positionEvent) {
    //
    //        Log.d(TAG, ".doJobUp" + " - BEGIN");
    //        
    //        // calcul de la case en fonction de la position
    //        //        Point caseEvent = getCase(position);
    //
    //        boolean action = false;
    //
    //        /** selection d'un joueur **/
    //        // on verifie si un joueur est deja selectionne
    //        if (Flags.getInstance().isPlayerSelected()) {
    //            // on recupere la cle du joueur selectionne
    //            PlayerKey playerKey = Flags.getInstance().getPlayerKeySelected();
    //            // on recupere le calque du joueur selectionne
    //            PlayerLayer playerSelectedLayer = lPlayerLayer.get(playerKey);
    //            // on recupere le joueur selectionne
    //            Player playerSelected = Arena.getInstance().getPlayer(Flags.getInstance().getPlayerKeySelected());
    //
    //            // on verifie si il y a une action de deplacement
    //            if (playerSelectedLayer.isMoving(positionEvent)) {
    //                // on deplace le joueur
    //                playerSelected.moveForward();
    //                action = true;
    //                // FIXME
    //                //                if (Arena.getInstance().isOwnerBall() && Arena.getInstance().getOwnerBall() == playerSelected.getPlayerKey()) {
    //                //
    //                //                }
    //            }
    //
    //            // on verifie si il y a une action de rotation horaire
    //            if (playerSelectedLayer.isTurningNormal(positionEvent)) {
    //                playerSelected.rotateH();
    //                action = true;
    //            }
    //            // rotation "anti" horaire
    //            if (playerSelectedLayer.isTurningReverse(positionEvent)) {
    //                playerSelected.rotateAH();
    //                action = true;
    //            }
    //
    //            /** on verifie si une passe n'est pas effectuee **/
    //            // FIXME PASSE
    //            //            if (!action && Flags.getInstance().isBallSelected() && playerSelectedLayer.isPassing(positionEvent)) {
    //            //            if (!action && Flags.getInstance().isBallSelected() && Util.getDistance(playerSelected.getPosition(), positionEvent) <= 400) {
    //            if (!action && Flags.getInstance().isBallSelected() && Util.isPassePossible(playerSelected, positionEvent)) {
    //                // calcul de la position de la balle
    //                Point positionReelle = Util.getPositionPasse(Arena.getInstance().getPositionBall(), positionEvent);
    //                // changement de la position du ballon
    ////                Arena.getInstance().setPositionBall(positionReelle);
    //                
    //                
    //                
    //                // on calcule le delta des ordonnes des points
    //                int deltaX = Util.getDeltaX(Arena.getInstance().getPositionBall(), positionReelle);
    //                // on calcule le delta des abcisses des points
    //                int deltaY = Util.getDeltaY(Arena.getInstance().getPositionBall(), positionReelle);
    //                // on recupere le maximum de ces 2 delta
    //                int deltaMax = Math.max(Math.abs(deltaX), Math.abs(deltaY));
    //                // on en deduit le nombre de sequence
    //                int nbSequence = deltaMax / 10;
    //                
    //                int incrementX = deltaX / nbSequence;
    //                int incrementY = deltaY / nbSequence;
    //                
    //                for (int i = 0; i < nbSequence; i++) {
    //                    Point positionBall = Arena.getInstance().getPositionBall();
    //                    Point positionIntermediaire = new Point(positionBall.x + incrementX, positionBall.y + incrementY);
    //                    
    //                    Arena.getInstance().setPositionBall(positionIntermediaire);
    //                    
    //                    Log.w(TAG, "TEST");
    //                }
    //                
    //                Arena.getInstance().setPositionBall(positionReelle);
    //                
    //                
    //                // deselection du proprietaire du ballon
    //                Arena.getInstance().setOwnerBall(null);
    //            }
    //
    //            if (!action) {
    //                // on enleve les indicateurs sur la selection du joueur
    //                Flags.getInstance().unselectPlayer();
    //                Flags.getInstance().initPlayerKeySelected();
    //                // on enleve les indicateurs sur la selection du ballon
    //                Flags.getInstance().unselectBall();
    //            }
    //
    //        }
    //
    //        if (!action) {
    //            // on recherche si un joueur a ete selectionne
    //            Player playerSelected = getPlayer(positionEvent);
    //
    //            // si on trouve un joueur
    //            if (playerSelected != null) {
    //                // on ajoute les indicateurs sur la selection du joueur
    //                Flags.getInstance().selectPlayer();
    //                Flags.getInstance().addPlayerKeySelected(playerSelected.getPlayerKey());
    //
    //                //
    //                if (playerSelected.getPlayerKey().equals(Arena.getInstance().getOwnerBall())) {
    //                    Flags.getInstance().selectBall();
    //                }
    //            }
    //            // si on ne trouve pas de joueur 
    //            else if (playerSelected == null) {
    //                // on enleve les indicateurs sur la selection du joueur
    //                Flags.getInstance().unselectPlayer();
    //                Flags.getInstance().initPlayerKeySelected();
    //            }
    //        }
    //
    //        // FIXME gestion de tour
    //        /** **/
    //        // On verifie si un joueur a recuperer le ballon 
    //        PlayerKey newOwnerBall = Arena.getInstance().inteceptBall();
    //        // On verifie si un joueur est trouve et qu'il ne s'agit pas du meme joueur possedant deja le ballon
    //        if (newOwnerBall != null && Arena.getInstance().getOwnerBall() != newOwnerBall) {
    //            // definition du joueur possedant le ballon
    //            Arena.getInstance().setOwnerBall(newOwnerBall);
    //        }
    //
    //        Log.d(TAG, ".doJobUp" + " - END");
    //    }

    public void onDraw(Canvas canvas) {

        Log.v(TAG, this.getClass().getName() + ".onDraw" + " - BEGIN");

        //
        
        
        // dessin du terrain
        drawArena(canvas);

        //
        drawSurface(canvas);

        // dessin de la grille
        //        drawGrid(canvas);

        // dessin des selections possibles du ballon
        //         drawSelectionBall(canvas);
        // dessin des effets
        //                drawEffects(canvas);
        // dessin des joueurs
        drawPlayers(canvas);

        if (Flags.getInstance().isPassSelected()) {
            // dessin de la grille
            drawPassFilter(canvas);
        }

        // dessin du ballon
        drawBall(canvas);

        //
        drawGoal(canvas);

        Log.v(TAG, this.getClass().getName() + ".onDraw" + " - END");
    }

    /*
     * dessine le terrain
     */
    private void drawArena(Canvas canvas) {

        Log.v(TAG, this.getClass().getName() + ".drawArena" + " - BEGIN");

        // calcul des dimensions du terrain

        //        new Rect(x, y, NB_X_CASE * W_CASE, NB_Y_CASE * H_CASE)

        img_terrain.setBounds(0, 0, /** getWidthLayer() **/
        NB_X_CASE * W_CASE, /* getHeightLayer() */NB_Y_CASE * H_CASE);
        // affichage du terrain
        img_terrain.draw(canvas);

        Log.v(TAG, this.getClass().getName() + ".drawArena" + " - END");
    }

    /*
     * dessine les surfaces
     */
    private void drawSurface(Canvas canvas) {

        Paint paintRed = new Paint();
        paintRed.setColor(Color.RED);
        paintRed.setAlpha(50);
        //
        canvas.drawRect(966, 168, 1134, 504, paintRed);

        //
        Paint paintBlue = new Paint();
        paintBlue.setColor(Color.BLUE);
        paintBlue.setAlpha(50);
        //
        canvas.drawRect(42, 168, 210, 504, paintBlue);

    }

    /*
     * dessine GOAL
     */
    private void drawGoal(Canvas canvas) {

        if (Arena.getInstance().isEndGame()) {
            Paint paintYellow = new Paint();
            paintYellow.setColor(Color.YELLOW);
            //
            canvas.drawText("GOOOOOOAAAAALL !!", 400, 200, paintYellow);
        }

    }

    /*
     * dessine la grille
     */
    private void drawGrid(Canvas canvas) {
        Log.v(TAG, this.getClass().getName() + ".drawGrid" + " - BEGIN");

        // // AGARDER : effet visuel interessant
        // // Paint mLinePaint2 = new Paint();
        // // mLinePaint2.setAntiAlias(true);
        // // mLinePaint2.setARGB(255, 255, 255, 0);
        // // for (int i = 0; i < (X_MAX+2)*3; i++) {
        // // if (i%3 == 0) {
        // // canvas.drawLine(i*H_CASE/3, 0, i*H_CASE, H_BACKGROUND,
        // mLinePaint);
        // // } else {
        // // canvas.drawLine(i*H_CASE/3, 0, i*H_CASE, H_BACKGROUND,
        // mLinePaint2);
        // // }
        // // }
        // // for (int j = 0; j < (Y_MAX+2)*3; j++) {
        // // if (j%3 == 0) {
        // // canvas.drawLine(0, j*W_CASE/3, W_BACKGROUND, j*W_CASE,
        // mLinePaint);
        // // } else {
        // // canvas.drawLine(0, j*W_CASE/3, W_BACKGROUND, j*W_CASE,
        // mLinePaint2);
        // // }
        // //
        // // }
        //

        //        for (int i = 0; i < (Constants.X_MAX + 2) * 3; i++) {
        //            if (i % 3 == 0) {
        //                // affichage des lignes principales
        //                canvas.drawLine(i * H_CASE / 3, 0, i * H_CASE / 3, NB_Y_CASE * H_CASE, paintGrid1);
        //            } else {
        //                // affichage des lignes secondaires
        //                canvas.drawLine(i * H_CASE / 3, 0, i * H_CASE / 3, NB_Y_CASE * H_CASE, paintGrid2);
        //            }
        //        }
        //        for (int j = 0; j < (Constants.Y_MAX + 2) * 3; j++) {
        //            if (j % 3 == 0) {
        //                // affichage des lignes principales
        //                canvas.drawLine(0, j * W_CASE / 3, NB_X_CASE * W_CASE, j * W_CASE / 3, paintGrid1);
        //            } else {
        //                // affichage des lignes secondaires
        //                canvas.drawLine(0, j * W_CASE / 3, NB_X_CASE * W_CASE, j * W_CASE / 3, paintGrid2);
        //            }
        //
        //        }

        Log.v(TAG, this.getClass().getName() + ".drawGrid" + " - END");
    }

    /*
     * dessine le ballon
     */
    private void drawBall(Canvas canvas) {

        Log.v(TAG, this.getClass().getName() + ".drawBall" + " - BEGIN");

        /** affichage du ballon **/
        // calcul du cadre pour affichage du ballon
        Rect rectBall = Util.getLayoutDrawable(Arena.getInstance().getPositionBall(), img_ball.getMinimumWidth(), img_ball.getMinimumHeight());
        // on affiche le ballon
        img_ball.setAlpha(255);
        img_ball.setBounds(rectBall);
        img_ball.draw(canvas);
        if (Flags.getInstance().isPasseDone() && ((!Arena.getInstance().isTeamAStep() && !Arena.getInstance().isTeamBStep())
                || (Arena.getInstance().isTeamBStep() && Arena.getInstance().isOwnerBall() && !Arena.getInstance().getOwnerBall().isbTeamA())
                || (Arena.getInstance().isTeamAStep() && Arena.getInstance().isOwnerBall() && Arena.getInstance().getOwnerBall().isbTeamA()))) {
            
            Paint paint = new Paint();
            paint.setColor(Color.BLUE);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
            canvas.drawOval(new RectF(rectBall), paint);
        }

        /** affichage du point de chute du ballon selectionne pour une passe **/
        if (mPass != null && !(Arena.getInstance().isTeamBStep() && Arena.getInstance().isOwnerBall() && Arena.getInstance().getOwnerBall().isbTeamA())
                && !(Arena.getInstance().isTeamAStep() && Arena.getInstance().isOwnerBall() && !Arena.getInstance().getOwnerBall().isbTeamA())) {
            // calcul du cadre pour affichage du point de chute selectionne
            Rect rectPositionSelected = Util.getLayoutDrawable(mPass, img_ball.getMinimumWidth(), img_ball.getMinimumHeight());
            // on affiche le point de chute selectionne
            img_ball.setAlpha(255);
            img_ball.setBounds(rectPositionSelected);
            img_ball.draw(canvas);
            
            Paint paint = new Paint();
            paint.setColor(Color.GREEN);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
            canvas.drawOval(new RectF(rectPositionSelected), paint);
        }

        Log.v(TAG, this.getClass().getName() + ".drawBall" + " - END");
    }

    /*
     * dessine le filtre pour effectuer une passe
     */
    private void drawPassFilter(Canvas canvas) {

        Log.v(TAG, this.getClass().getName() + ".drawPassFilter" + " - BEGIN");

        // on verifie si un joueur possede le ballon
        if (Arena.getInstance().isOwnerBall()) {
            // on recupere le joueur possedant le ballon
            Player player = Arena.getInstance().getOwnerBall();
            // on recupere la position du joueur
            Point position = player.getPosition();

            Bitmap arenaFilter = makeArenaFilter();
            Bitmap passFilter = makePassFilter(position, 600, 200);

            /** **/
            Paint paint = new Paint();
            paint.setFilterBitmap(false);
            int W = NB_X_CASE * W_CASE;
            int H = NB_Y_CASE * H_CASE;
            int x = 0;
            int y = 0;

            Bitmap bm = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(bm);

            // draw the src/dst example into our offscreen bitmap
            int sc = c.saveLayer(x, y, x + W, y + H, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG
                    | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
            //            canvas.translate(x, y);

            //
            //            c.rotate(player.getDirection(), position.x, position.y);
            //            c.drawBitmap(passFilter, 0, 0, paint);
            //            c.restore();
            //
            //            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
            c.drawBitmap(arenaFilter, 0, 0, paint);
            //            paint.setXfermode(null);

            c.rotate(player.getDirection(), position.x, position.y);
            c.drawBitmap(passFilter, 0, 0, paint);
            c.restore();

            c.restoreToCount(sc);
            paint.setAlpha(150);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.OVERLAY));

            canvas.drawBitmap(bm, 0, 0, paint);
        }

        Log.v(TAG, this.getClass().getName() + ".drawPassFilter" + " - END");
    }

    /*
     * cree une image blanche pour indiquer la zone (avant) de selection de
     * passe
     */
    private Bitmap makePassFilter(Point position, int distancePass, int anglePass) {
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        //        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        // on cree la zone de selection en fonction de la position du joueur et des ses capacites 
        //        RectF rectPass = new RectF(position.x - distancePass, position.y - anglePass, position.x + distancePass, position.y + anglePass);
        //        p.setColor(Color.WHITE);
        // on ajoute du flou sur la zone de selection
        int max = Math.max(distancePass, anglePass);
        MaskFilter gradientFilter = new BlurMaskFilter(max, BlurMaskFilter.Blur.NORMAL);
        //        p.setMaskFilter(gradientFilter);
        // on dessine la zone de selection
        //        canvas.drawOval(rectPass, p);     
        //        Paint paintBlack = new Paint();
        //        paintBlack.setColor(Color.BLACK);
        //        // on ecrase l'arriere de la zone de selection
        //        canvas.drawRect(new RectF(position.x - 2000, position.y - 1000, position.x, position.y  + 1000), paintBlack);
        //        
        //        

        ShapeDrawable mDrawable = new ShapeDrawable(new ArcShape(-90, 180));
        Shader colorGradient = new LinearGradient(position.x, position.y, position.x + distancePass, position.y, new int[] { 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000, 0xFF000000 }, null,
                Shader.TileMode.CLAMP);
        //        mDrawable.getPaint().setShader(colorGradient);
        mDrawable.getPaint().setColor(Color.WHITE);
        //        mDrawable.getPaint().setColor(Color.YELLOW);
        mDrawable.getPaint().setMaskFilter(gradientFilter);

        Rect rectCone = new Rect(position.x - distancePass, position.y - anglePass, position.x + distancePass, position.y + anglePass);
        mDrawable.setBounds(rectCone);
        mDrawable.draw(canvas);

        return bitmap;
    }

    /*
     * cree une image noire de la taille du terrain
     */
    private Bitmap makeArenaFilter() {
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        // on dessine sur l'ensemble du terrain
        canvas.drawRect(getLayout(), paint);
        return bitmap;
    }

    /*
     * dessine les joueurs
     */
    private void drawPlayers(Canvas canvas) {

        Log.v(TAG, this.getClass().getName() + ".drawPlayers" + " - BEGIN");

        // iteration sur tous les calques de joueurs
        for (PlayerLayer playerLayer : lPlayerLayer.values()) {
            // dessine un joueur
            playerLayer.onDraw(canvas);
        }

        Log.v(TAG, this.getClass().getName() + ".drawPlayers" + " - END");
    }

    /*
     * dessine les effets
     */
    private void drawEffects(Canvas canvas) {

        Log.v(TAG, this.getClass().getName() + ".drawEffects" + " - BEGIN");

        Log.v(TAG, this.getClass().getName() + ".drawEffects" + " - END");
    }

    /*
     * retourne un joueur si on clique sur son calque
     */
    private Player getPlayer(Point positionEvent) {
        // initialisation du joueur a retourner
        Player player = null;
        // on parcourt la liste des calques de joueur
        for (PlayerLayer playerLayer : lPlayerLayer.values()) {
            // on verifie si le click appartient au calque
            if (playerLayer.isInside(positionEvent)) {
                // affectation du joueur
                player = playerLayer.getPlayer();
            }
        }

        return player;
    }

    public Map<PlayerKey, PlayerLayer> getlPlayerLayer() {
        return lPlayerLayer;
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        // declaration du canevas
        Canvas canvas = null;

        try {
            // recuperation et initialisation du canevas
            canvas = surfaceHolder.lockCanvas(null);
            // affichage de la vue
            onDraw(canvas);
        } finally {
            // liberation du canevas
            if (canvas != null) {
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    }

    private RectF getLayout() {
        return new RectF(0, 0, NB_X_CASE * W_CASE, NB_Y_CASE * H_CASE);
    }

    private int getWidthLayout() {
        return (int) getLayout().width();
    }

    private int getHeightLayout() {
        return (int) getLayout().height();
    }

    public Point getmPass() {
        return mPass;
    }

    public void setmPass(Point mPass) {
        this.mPass = mPass;
    }

}
